﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using SGP;

namespace TileEditor
{
	public partial class MainForm : Form
	{
		bool looping = true;

		CSGP_Direct3D DX = CSGP_Direct3D.GetInstance();
		CSGP_TextureManager TM = CSGP_TextureManager.GetInstance();
		Bitmap usedImage;
		public int tilesetID = -1;
		
		string workingDir;
		string tileSetPath;

		int numLayers = 1;

		Size tilesetSize = new Size(4, 2);
		Size tileSize = new Size(64, 64);
		
		Size mapSize = new Size(10, 10);
		Tile selectedTile;
		int selectedLayerCount;
		Layer[] renderLayers;

		Point p;

		public Size TilesetSize
		{
			get { return tilesetSize; }
			set { tilesetSize = value; }
		}
		public Size TileSize
		{
			get { return tileSize; }
			set { tileSize = value; }
		}
		public Size MapSize
		{
			get { return mapSize; }
			set { mapSize = value; }
		}
		public bool Looping
		{
			get { return looping; }
			set { looping = value; }
		}
		public MainForm()
		{
			InitializeComponent();

			DX.Initialize(TileSetPanel, false);
			DX.AddRenderTarget(MapPanel);

			TM.Initialize(DX.Device, DX.Sprite);

			workingDir = Application.StartupPath;

			EventCBox.SelectionStart = 0;
			TileTypeCBox.SelectionStart = 0;
		}
		private void Form1_Load(object sender, EventArgs e)
		{
			Layer baseLayer = new Layer();
			LayerLBox.Items.Add(baseLayer);

			LayerLBox.SetSelected(0, true);
			Layer currLayer = (Layer)LayerLBox.SelectedItem;

			TileWidthNUD.Value = Convert.ToDecimal(TileSize.Width);
			TileHeightNUD.Value = Convert.ToDecimal(TileSize.Height);

			MapWidthNUD.Value = Convert.ToDecimal(MapSize.Width);
			MapHeightNUD.Value = Convert.ToDecimal(MapSize.Height);

			baseLayer.map = new Tile[MapSize.Width, MapSize.Height];
			baseLayer.events = new string[MapSize.Width, MapSize.Height];

			for (int x = 0; x < MapSize.Width; x++)
			{
				for (int y = 0; y < MapSize.Height; y++)
				{
					baseLayer.map[x, y] = selectedTile;
					baseLayer.events[x, y] = "";
				}
			}

			EventCBox.SelectedIndex = 0;
			TileTypeCBox.SelectedIndex = 0;

			MapScrollPanel.AutoScrollMinSize = new Size(MapSize.Width * TileSize.Width, MapSize.Height * TileSize.Height);
		}
		public new void Update()
		{
			Layer currLayer = (Layer)LayerLBox.SelectedItem;

			if (tileSize.Width != Convert.ToInt32(TileWidthNUD.Value) || tileSize.Height != Convert.ToInt32(TileHeightNUD.Value))
			{
				tileSize.Width = Convert.ToInt32(TileWidthNUD.Value);
				tileSize.Height = Convert.ToInt32(TileHeightNUD.Value);

				if (tilesetID > -1)
				{
					Size imageSize = new Size(0, 0);

					imageSize.Height = TM.GetTextureHeight(tilesetID);
					imageSize.Width = TM.GetTextureWidth(tilesetID);
					TilesetSize = new Size(imageSize.Width / TileSize.Width, imageSize.Height / TileSize.Height);

					TileSetScrollPanel.AutoScrollMinSize = new Size(TM.GetTextureWidth(tilesetID), TM.GetTextureHeight(tilesetID));
				}
			}
			

			tilesetSize.Width = Convert.ToInt32(TileSetWidthNUD.Value);
			tilesetSize.Height = Convert.ToInt32(TileSetHeightNUD.Value);

			if (mapSize.Width != Convert.ToInt32(MapWidthNUD.Value) || mapSize.Height != Convert.ToInt32(MapHeightNUD.Value))
			{
				foreach(Layer layer in LayerLBox.Items)
				{
					Size tempSize = mapSize;
					Tile[,] tempMap = new Tile[mapSize.Width, mapSize.Height];
					string[,] tempEvents = new string[mapSize.Width, mapSize.Height];
					for (int x = 0; x < mapSize.Width; x++)
					{
						for (int y = 0; y < mapSize.Height; y++)
						{
							tempMap[x, y] = layer.map[x, y];
							tempEvents[x, y] = layer.events[x, y];

						}
					}

					int newWidth = Convert.ToInt32(MapWidthNUD.Value);
					int newHeight = Convert.ToInt32(MapHeightNUD.Value);
					layer.map = new Tile[newWidth, newHeight];
					layer.events = new string[newWidth, newHeight];

					for (int x = 0; x < tempSize.Width && x < newWidth; x++)
					{
						for (int y = 0; y < tempSize.Height && y < newHeight; y++)
						{
							layer.map[x, y] = tempMap[x, y];
							layer.events[x, y] = tempEvents[x, y];
						}
					}
				}
				mapSize.Width = Convert.ToInt32(MapWidthNUD.Value);
				mapSize.Height = Convert.ToInt32(MapHeightNUD.Value);

				MapScrollPanel.AutoScrollMinSize = new Size(MapSize.Width * TileSize.Width, MapSize.Height * TileSize.Height);
			}

			ArrayList selectedLayers = new ArrayList();
			foreach(object selected in LayerLBox.SelectedItems)
			{
				selectedLayers.Add(selected);
			}
			selectedLayerCount = selectedLayers.Count;
			renderLayers = new Layer[selectedLayerCount];
			for (int i = 0; i < selectedLayerCount; i++)
			{
				renderLayers[i] = (Layer)selectedLayers[i];
			}
		}
		public void Render()
		{
			DX.Clear(TileSetPanel, Color.White);
			DX.DeviceBegin();
			DX.SpriteBegin();
			
			if (tilesetID > -1)
			{
				TM.Draw(tilesetID, 0, 0);
			
				Rectangle seperator = new Rectangle();
				seperator.Size = TileSize;
			
				for (int row = 0; row < TilesetSize.Height; row++)
				{
					for (int col = 0; col < TilesetSize.Width; col++)
					{
						seperator.Location = new Point(col * TileSize.Width, row * TileSize.Height);
						DX.DrawHollowRect(seperator, Color.Black, 1);
					}
				}
			
				Point selected = new Point(selectedTile.X * tileSize.Width, selectedTile.Y * tileSize.Height);
				Rectangle selectedRect = new Rectangle(selected, tileSize);
				DX.DrawHollowRect(selectedRect, Color.Red, 2);
			}
			
			DX.SpriteEnd();
			DX.DeviceEnd();
			DX.Present();

			DX.Clear(MapPanel, Color.AliceBlue);
			DX.DeviceBegin();
			DX.SpriteBegin();

			for (int i = 0; i < selectedLayerCount; i++)
			{
				if (renderLayers[i].renderTiles)
				{
					for (int x = 0; x < mapSize.Width; x++)
					{
						for (int y = 0; y < mapSize.Height; y++)
						{
							if (renderLayers[i].map[x, y].Render)
							{
								Rectangle destRect = Rectangle.Empty;
								destRect.X = x * tileSize.Width;
								destRect.Y = y * tileSize.Height;
								destRect.Size = tileSize;
								
								Rectangle srcRect = Rectangle.Empty;
								srcRect.X = renderLayers[i].map[x, y].X * tileSize.Width;
								srcRect.Y = renderLayers[i].map[x, y].Y * tileSize.Height;
								srcRect.Size = tileSize;

								TM.Draw(tilesetID, x * TileSize.Width, y * TileSize.Height, 1, 1, srcRect);
							}
						}
					}
				}

				if (true)
				{
					for (int x = 0; x < mapSize.Width; x++)
					{
						for (int y = 0; y < mapSize.Height; y++)
						{
							if (renderLayers[i].events[x, y] == "TILECOLLISION")
							{
								Rectangle destRect = Rectangle.Empty;
								destRect.X = x * tileSize.Width;
								destRect.Y = y * tileSize.Height;
								destRect.Size = tileSize;
							
								Color collisionColor = Color.FromArgb(128, Color.Red);
							
								DX.DrawRect(destRect, collisionColor);
							}
							else if (renderLayers[i].events[x, y] == "SPAWN_PLAYER")
							{
								Rectangle destRect = Rectangle.Empty;
								destRect.X = x * tileSize.Width;
								destRect.Y = y * tileSize.Height;
								destRect.Size = tileSize;
							
								Color collisionColor = Color.FromArgb(128, Color.Purple);
							
								DX.DrawRect(destRect, collisionColor);
							}
							else if(renderLayers[i].events[x, y] == "SPAWN_GOBLIN" ||
									renderLayers[i].events[x, y] == "SPAWN_KNIGHT" ||
									renderLayers[i].events[x, y] == "SPAWN_ELF" ||
									renderLayers[i].events[x, y] == "SPAWN_ARCHER" ||
									renderLayers[i].events[x, y] == "SPAWN_BAT" ||
									renderLayers[i].events[x, y] == "SPAWN_SPIDER" ||
									renderLayers[i].events[x, y] == "SPAWN_OGRE" ||
									renderLayers[i].events[x, y] == "SPAWN_GIANT_SPIDER" ||
									renderLayers[i].events[x, y] == "SPAWN_VAMPIRE" ||
									renderLayers[i].events[x, y] == "SPAWN_DRAGON")
							{
								Rectangle destRect = Rectangle.Empty;
								destRect.X = x * tileSize.Width;
								destRect.Y = y * tileSize.Height;
								destRect.Size = tileSize;
							
								Color collisionColor = Color.FromArgb(128, Color.Green);
							
								DX.DrawRect(destRect, collisionColor);
							}
							else if(renderLayers[i].events[x, y] == "SPAWN_DASH_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_BACKDASH_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_SLIDING_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_DOUBLEJUMP_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_WALLCLIMB_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_ARCANESHOT_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_ARCANEBEAM_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_ELECTRONSHOT_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_PHOTONSHOT_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_VAMPIRICMAGNET_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_DOUBLESHOT_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_SHOCKWAVE_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_FIREBLAST_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_SOLARFLARE_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_EXPLOSIVE_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_SEEKERSLUDGE_AUGMENT" ||
									renderLayers[i].events[x, y] == "SPAWN_MAGICMISSILE_AUGMENT")
							{
								Rectangle destRect = Rectangle.Empty;
								destRect.X = x * tileSize.Width;
								destRect.Y = y * tileSize.Height;
								destRect.Size = tileSize;
							
								Color collisionColor = Color.FromArgb(128, Color.Blue);
							
								DX.DrawRect(destRect, collisionColor);
							}
							else if(renderLayers[i].events[x, y] == "SPAWN_BASE_PORTAL" ||
									renderLayers[i].events[x, y] == "SPAWN_LEVEL1_PORTAL" ||
									renderLayers[i].events[x, y] == "SPAWN_LEVEL2_PORTAL" ||
									renderLayers[i].events[x, y] == "SPAWN_LEVEL3_PORTAL" ||
									renderLayers[i].events[x, y] == "SPAWN_LEVEL4_PORTAL" ||
									renderLayers[i].events[x, y] == "SPAWN_UCC_PORTAL" ||
									renderLayers[i].events[x, y] == "SPAWN_WARP_PORTAL")
							{
								Rectangle destRect = Rectangle.Empty;
								destRect.X = x * tileSize.Width;
								destRect.Y = y * tileSize.Height;
								destRect.Size = tileSize;
							
								Color collisionColor = Color.FromArgb(128, Color.Yellow);
							
								DX.DrawRect(destRect, collisionColor);
							}
							else if (renderLayers[i].events[x, y] == "SPAWN_LADDER" ||
									renderLayers[i].events[x, y] == "SPAWN_STAIRS" ||
									renderLayers[i].events[x, y] == "SPAWN_BULLETTYPE_AUGMENTTABLE" ||
									renderLayers[i].events[x, y] == "SPAWN_SHOTSTYLE_AUGMENTTABLE" ||
									renderLayers[i].events[x, y] == "SPAWN_MOVEMENT_AUGMENTTABLE")
							{
								Rectangle destRect = Rectangle.Empty;
								destRect.X = x * tileSize.Width;
								destRect.Y = y * tileSize.Height;
								destRect.Size = tileSize;

								Color collisionColor = Color.FromArgb(128, Color.Orange);

								DX.DrawRect(destRect, collisionColor);
							}
						}
					}
				}

				Rectangle seperator = new Rectangle();
				seperator.Size = TileSize;
				
				for (int row = 0; row < MapSize.Height; row++)
				{
					for (int col = 0; col < MapSize.Width; col++)
					{
						seperator.Location = new Point(col * TileSize.Width, row * TileSize.Height);
						DX.DrawHollowRect(seperator, Color.Black, 1);
					}
				}
			}
			
			DX.SpriteEnd();
			DX.DeviceEnd();
			DX.Present();
			
		}

		private void Form1_FormClosing(object sender, FormClosingEventArgs e)
		{
			Looping = false;
		}
		private void newToolStripMenuItem_Click(object sender, EventArgs e)
		{

			foreach (Layer layer in LayerLBox.Items)
			{
				int newWidth = Convert.ToInt32(MapWidthNUD.Value);
				int newHeight = Convert.ToInt32(MapHeightNUD.Value);

				layer.map = new Tile[newWidth, newHeight];
				layer.events = new string[newWidth, newHeight];

			}
			mapSize.Width = Convert.ToInt32(MapWidthNUD.Value);
			mapSize.Height = Convert.ToInt32(MapHeightNUD.Value);

			MapScrollPanel.AutoScrollMinSize = new Size(MapSize.Width * TileSize.Width, MapSize.Height * TileSize.Height);
		}
		private void openToolStripMenuItem_Click(object sender, EventArgs e)
		{
			OpenFileDialog dlg = new OpenFileDialog();
			dlg.Filter = "All Files(*.*)|*.*|Map Files(*.xml)|*.xml";
			dlg.FilterIndex = 2;

			if (DialogResult.OK == dlg.ShowDialog())
			{
				LayerLBox.Items.Clear();
				
				XElement xRoot = XElement.Load(dlg.FileName);
				XAttribute xVer = xRoot.Attribute("version");
				//int ver = Convert.ToInt32(xVer.Value);
				XAttribute xLRows = xRoot.Attribute("rows");
				MapHeightNUD.Value = Convert.ToInt32(xLRows.Value);
				mapSize.Height = Convert.ToInt32(MapHeightNUD.Value);
				XAttribute xLCols = xRoot.Attribute("cols");
				MapWidthNUD.Value = Convert.ToInt32(xLCols.Value);
				mapSize.Width = Convert.ToInt32(MapWidthNUD.Value);
				XAttribute xTHeight = xRoot.Attribute("tile_height");
				TileHeightNUD.Value = Convert.ToInt32(xTHeight.Value);
				tileSize.Height = Convert.ToInt32(TileHeightNUD.Value);
				XAttribute xTWidth = xRoot.Attribute("tile_width");
				TileWidthNUD.Value = Convert.ToInt32(xTWidth.Value);
				tileSize.Width = Convert.ToInt32(TileWidthNUD.Value);
				XAttribute xNumLayers = xRoot.Attribute("num_layers");
				numLayers = Convert.ToInt32(xNumLayers.Value);
				
				XElement xTileSet = xRoot.Element("Tileset");
				XAttribute xTSRows = xTileSet.Attribute("rows");
				TileSetHeightNUD.Value = Convert.ToInt32(xTSRows.Value);
				tilesetSize.Height = Convert.ToInt32(TileSetHeightNUD.Value);
				XAttribute xTSCols = xTileSet.Attribute("cols");
				TileSetWidthNUD.Value = Convert.ToInt32(xTSCols.Value);
				tilesetSize.Width = Convert.ToInt32(TileSetWidthNUD.Value);

				string path = Path.GetDirectoryName(dlg.FileName);
				tileSetPath = xTileSet.Value;
				tilesetID = TM.LoadTexture(path + "\\" + tileSetPath);

				usedImage = new Bitmap(path + "\\" + tileSetPath);
				TileSetScrollPanel.AutoScrollMinSize = new Size(TM.GetTextureWidth(tilesetID), TM.GetTextureHeight(tilesetID));
				selectedTile = new Tile(0, 0, true, TileTypeCBox.SelectedText);

				if (TileSetPanel.IsHandleCreated)
				{
					DX.Resize(TileSetPanel, false);
				}

				IEnumerable<XElement> xLayers = xRoot.Elements("Layer");

				for (int layerIndex = 0; layerIndex < numLayers; layerIndex++)
				{
					XElement xLayer = xLayers.ElementAt<XElement>(layerIndex);
					Layer currLayer = new Layer();
					
					XAttribute xName = xLayer.Attribute("name");
					currLayer.name = xName.Value;
										
					currLayer.map = new Tile[(int)MapWidthNUD.Value, (int)MapHeightNUD.Value];
					currLayer.events = new string[(int)MapWidthNUD.Value, (int)MapHeightNUD.Value];

					TileSetScrollPanel.AutoScrollMinSize = new Size(TM.GetTextureWidth(tilesetID), TM.GetTextureHeight(tilesetID));
					MapScrollPanel.AutoScrollMinSize = new Size(MapSize.Width * TileSize.Width, MapSize.Height * TileSize.Height);

					IEnumerable<XElement> xTiles = xLayer.Elements();

					for (int tileIndex = 0; tileIndex < MapHeightNUD.Value * MapWidthNUD.Value; tileIndex++)
					{
						XElement xTile = xTiles.ElementAt<XElement>(tileIndex);
						XAttribute xTSX = xTile.Attribute("tileset_x");
						currLayer.map[tileIndex % (int)MapWidthNUD.Value, tileIndex / (int)MapWidthNUD.Value].X = Convert.ToInt32(xTSX.Value);
						XAttribute xTSY = xTile.Attribute("tileset_y");
						currLayer.map[tileIndex % (int)MapWidthNUD.Value, tileIndex / (int)MapWidthNUD.Value].Y = Convert.ToInt32(xTSY.Value);
						XAttribute xCollide = xTile.Attribute("event");
						currLayer.events[tileIndex % (int)MapWidthNUD.Value, tileIndex / (int)MapWidthNUD.Value] = xCollide.Value;
						for(int i = 0; i < EventCBox.Items.Count; i++)
						{
							if (currLayer.events[tileIndex % (int)MapWidthNUD.Value, tileIndex / (int)MapWidthNUD.Value] == EventCBox.Items[i].ToString() || currLayer.events[tileIndex % (int)MapWidthNUD.Value, tileIndex / (int)MapWidthNUD.Value] == "")
							{
								break;
							}
							else if (currLayer.events[tileIndex % (int)MapWidthNUD.Value, tileIndex / (int)MapWidthNUD.Value] != EventCBox.Items[i].ToString() && i == EventCBox.Items.Count - 1)
							{
								EventCBox.Items.Add(currLayer.events[tileIndex % (int)MapWidthNUD.Value, tileIndex / (int)MapWidthNUD.Value]);
								break;
							}
						}
						
						XAttribute xType = xTile.Attribute("type");
						currLayer.map[tileIndex % (int)MapWidthNUD.Value, tileIndex / (int)MapWidthNUD.Value].Type = xType.Value;
						XAttribute xRender = xTile.Attribute("render");
						currLayer.map[tileIndex % (int)MapWidthNUD.Value, tileIndex / (int)MapWidthNUD.Value].Render = Convert.ToBoolean(xRender.Value);
					}
					LayerLBox.Items.Add(currLayer);
					LayerLBox.SetSelected(layerIndex, true);
				}
			}

			if (TileSetPanel.IsHandleCreated)
			{
				DX.Resize(TileSetPanel, false);
			}

			ArrayList selectedLayers = new ArrayList();
			foreach (object selected in LayerLBox.Items)
			{
				selectedLayers.Add(selected);
			}

			selectedLayerCount = selectedLayers.Count;
			renderLayers = new Layer[selectedLayerCount];
			for (int i = 0; i < selectedLayerCount; i++)
			{
				renderLayers[i] = (Layer)selectedLayers[i];
			}
		}
		private void importTilesetToolStripMenuItem_Click(object sender, EventArgs e)
		{
			OpenFileDialog dlg = new OpenFileDialog();
			dlg.Title = "Tile Set Selector";
			dlg.InitialDirectory = workingDir;

			dlg.Filter = "All Files(*.*)|*.*|Image Files(*.bmp, *.jpg, *.gif, *.png)|*.bmp;*.jpg;*.gif;*.png";
			dlg.FilterIndex = 2;

			if (DialogResult.OK == dlg.ShowDialog())
			{
				//Layer currLayer = (Layer)LayerLBox.SelectedItem;

				tileSetPath = dlg.SafeFileName;
				tilesetID = TM.LoadTexture(dlg.FileName);
				
				usedImage = new Bitmap(dlg.FileName);

				TileWidthNUD.Value = Convert.ToDecimal(TileSize.Width);
				TileHeightNUD.Value = Convert.ToDecimal(TileSize.Height);

				Size imageSize = new Size(0, 0);
				imageSize.Height = TM.GetTextureHeight(tilesetID);
				imageSize.Width = TM.GetTextureWidth(tilesetID);
				TilesetSize = new Size(imageSize.Width / TileSize.Width, imageSize.Height / TileSize.Height);

				TileSetScrollPanel.AutoScrollMinSize = new Size(TM.GetTextureWidth(tilesetID), TM.GetTextureHeight(tilesetID));

				selectedTile = new Tile(0, 0, true, TileTypeCBox.SelectedText);

				if (TileSetPanel.IsHandleCreated)
				{
					DX.Resize(TileSetPanel, false);
				}
				if (MapPanel.IsHandleCreated)
				{
					DX.Resize(MapPanel, false);
				}
			}

		}
		private void saveToolStripMenuItem_Click(object sender, EventArgs e)
		{
			SaveFileDialog dlg = new SaveFileDialog();
			dlg.Filter = "All Files(*.*)|*.*|Map Files(*.xml)|*.xml";
			dlg.FilterIndex = 2;
			dlg.DefaultExt = "xml";

			if (DialogResult.OK == dlg.ShowDialog())
			{
				XElement xRoot = new XElement("Map");
				XAttribute xVer = new XAttribute("version", "");
				XAttribute xMRows = new XAttribute("rows", MapSize.Height);
				XAttribute xMCols = new XAttribute("cols", MapSize.Width);
				XAttribute xTHeight = new XAttribute("tile_height", TileSize.Height);
				XAttribute xTWidth = new XAttribute("tile_width", TileSize.Width);
				XAttribute xNumLayers = new XAttribute("num_layers", numLayers);
				
				xRoot.Add(xVer);
				xRoot.Add(xMRows);
				xRoot.Add(xMCols);
				xRoot.Add(xTHeight);
				xRoot.Add(xTWidth);
				xRoot.Add(xNumLayers);

				XElement xTileSet = new XElement("Tileset");
				XAttribute xTSRows = new XAttribute("rows", TilesetSize.Height);
				XAttribute xTSCols = new XAttribute("cols", TilesetSize.Width);
				xTileSet.Value = tileSetPath;

				xTileSet.Add(xTSRows);
				xTileSet.Add(xTSCols);
				xRoot.Add(xTileSet);

				foreach (Layer currLayer in LayerLBox.Items)
				{
					XElement xLayer = new XElement("Layer");
					XAttribute xName = new XAttribute("name", currLayer.name);

					xLayer.Add(xName);
					xRoot.Add(xLayer);

					for (int r = 0; r < MapSize.Height; r++)
					{
						for (int c = 0; c < MapSize.Width; c++)
						{
							XElement xTile = new XElement("Tile");

							XAttribute xTSX = new XAttribute("tileset_x", currLayer.map[c, r].X);
							XAttribute xTSY = new XAttribute("tileset_y", currLayer.map[c, r].Y);
							XAttribute xMX = new XAttribute("map_x", c);
							XAttribute xMY = new XAttribute("map_y", r);
							XAttribute xCollide;
							if(currLayer.events[c, r] != null)
							{
								xCollide = new XAttribute("event", currLayer.events[c, r]);
							}
							else
							{
								xCollide = new XAttribute("event", "");
							}
							XAttribute xType;
							if (currLayer.map[c, r].Type != null)
							{
								xType = new XAttribute("type", currLayer.map[c, r].Type);
							}
							else
							{
								xType = new XAttribute("type", "");
							}
							XAttribute xRender = new XAttribute("render", currLayer.map[c, r].Render);

							xTile.Add(xTSX);
							xTile.Add(xTSY);
							xTile.Add(xMX);
							xTile.Add(xMY);
							xTile.Add(xCollide);
							xTile.Add(xType);
							xTile.Add(xRender);
							xLayer.Add(xTile);
						}
					}
				}
				xRoot.Save(dlg.FileName);
				
				string path = Path.GetDirectoryName(dlg.FileName);
				try
				{
					usedImage.Save(path + "\\" + tileSetPath); 
				}
				catch
				{
					Bitmap bitmap = new Bitmap(usedImage.Width, usedImage.Height, usedImage.PixelFormat);
					Graphics g = Graphics.FromImage(bitmap);
					g.DrawImage(usedImage, new Point(0, 0));
					g.Dispose();
					usedImage.Dispose();
					bitmap.Save(path + "\\" + tileSetPath);
					usedImage = bitmap; // preserve clone        
				}
			}
		}
		private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
		{

		}
		private void exitToolStripMenuItem_Click(object sender, EventArgs e)
		{
			saveToolStripMenuItem_Click(sender, e);
			Close();
		}
		private void MainForm_Resize(object sender, EventArgs e)
		{
			if(MapPanel.IsHandleCreated)
			{
				DX.Resize(MapPanel, false);
			}
			if(TileSetPanel.IsHandleCreated)
			{
				DX.Resize(TileSetPanel, false);
			}
		}
		private void EditorContainer_Panel1_Resize(object sender, EventArgs e)
		{
			if (MapPanel.IsHandleCreated)
			{
				DX.Resize(MapPanel, false);
			}
		}
		private void EditorContainer_Panel2_Resize(object sender, EventArgs e)
		{
			if (TileSetPanel.IsHandleCreated)
			{
				DX.Resize(TileSetPanel, false);
			}
		}
		private void ToolContainer_Panel1_Resize(object sender, EventArgs e)
		{
			if (TileSetPanel.IsHandleCreated)
			{
				DX.Resize(TileSetPanel, false);
			}
		}
		private void MapPanel_Resize(object sender, EventArgs e)
		{
			if (MapPanel.IsHandleCreated)
			{
				DX.Resize(MapPanel, false);
			}
		}
		private void TileSetPanel_MouseClick(object sender, MouseEventArgs e)
		{
			if (e.X < (tileSize.Width * tilesetSize.Width) && e.Y < (tileSize.Height * tilesetSize.Height))
			{
				selectedTile.X = e.X / tileSize.Width;
				selectedTile.Y = e.Y / tileSize.Height;
			}
		}
		private void MapPanel_MouseMove(object sender, MouseEventArgs e)
		{
			if (e.Button == System.Windows.Forms.MouseButtons.Left)
			{
				MapPanel_MouseClick(sender, e);
			}
		}
		private void MapPanel_MouseClick(object sender, MouseEventArgs e)
		{
			if (e.Button == System.Windows.Forms.MouseButtons.Left && e.X < (mapSize.Width * tileSize.Width) && e.Y < (mapSize.Height * tileSize.Height))
			{
				int x = e.X / tileSize.Width;
				int y = e.Y / tileSize.Height;

				if (x >= renderLayers[selectedLayerCount - 1].map.GetLength(0) || y >= renderLayers[selectedLayerCount - 1].map.GetLength(1))
					return;

				selectedTile.Type = TileTypeCBox.Text;
				renderLayers[selectedLayerCount - 1].map[x, y] = selectedTile;
				renderLayers[selectedLayerCount - 1].events[x, y] = EventCBox.Text;
			}
			else if(e.Button == System.Windows.Forms.MouseButtons.Right && e.X < (mapSize.Width * tileSize.Width) && e.Y < (mapSize.Height * tileSize.Height))
			{
				DeleteTile.Show(new Point(e.X, e.Y));
			}
		}
		private void RenameLayerButton_Click(object sender, EventArgs e)
		{
			Layer currLayer = (Layer)LayerLBox.SelectedItem;
			currLayer.name = layerName.Text;

			LayerLBox.Items[LayerLBox.SelectedIndex] = currLayer;
		}
		private void AddLayerButton_Click(object sender, EventArgs e)
		{
			Layer layer = new Layer();

			numLayers++;
			if(layerName.Text == "")
			{
				layer.name = "Layer" + numLayers.ToString();
			}
			else
			{
				layer.name = layerName.Text;
			}

			layer.map = new Tile[MapSize.Width, MapSize.Height];
			layer.events = new string[MapSize.Width, MapSize.Height];

			layer.renderTiles = true;
			layer.renderCollision = false;

			Layer firstLayer = (Layer)LayerLBox.Items[0];
			
			LayerLBox.Items.Add(layer);
			LayerLBox.SetSelected(numLayers - 1, true);
		}
		private void RemoveLayerButton_Click(object sender, EventArgs e)
		{
			if(LayerLBox.SelectedIndex >= 1)
			{
				int selected = LayerLBox.SelectedIndex;
				LayerLBox.Items.RemoveAt(selected);
				LayerLBox.SetSelected(--selected, true);
				--numLayers;
			}
		}
		private void LayerLBox_MouseDown(object sender, MouseEventArgs e)
		{
			if (e.Button == System.Windows.Forms.MouseButtons.Right && e.X < LayerLBox.Width && e.Y < LayerLBox.Height)
			{
				//item index = click possition - autoscollposition.x / item height
				//owner drawn
				LayerOptions.Show(new Point(MainForm.MousePosition.X, MainForm.MousePosition.Y));
			}
		}
		private void deleteSelectedTIleToolStripMenuItem_Click(object sender, EventArgs e)
		{
			//Point p = MapPanel.PointToClient(MainForm.MousePosition);
			int x = p.X / tileSize.Width;
			int y = p.Y / tileSize.Height;

			renderLayers[selectedLayerCount - 1].map[x, y].Render = false;
			renderLayers[selectedLayerCount - 1].events[x, y] = "";
		}
		private void TileSetScrollPanel_Scroll(object sender, ScrollEventArgs e)
		{
			Render();
		}
		private void EditorContainer_Panel1_Scroll(object sender, ScrollEventArgs e)
		{
			Render();
		}
		private void MapPanel_MouseDown(object sender, MouseEventArgs e)
		{
			p = e.Location;
		}

		private void MapScrollPanel_Scroll(object sender, ScrollEventArgs e)
		{
			Render();
		}

		private void MapScrollPanel_Resize(object sender, EventArgs e)
		{
			if (MapPanel.IsHandleCreated)
			{
				DX.Resize(MapPanel, false);
			}
		}
	}
}
